package top.wuxiaohan.operatingSystemCourse.shell;

import top.wuxiaohan.operatingSystemCourse.kernel.Kernel;

import java.io.*;
import java.util.Scanner;

import static java.lang.System.exit;

/**
 * shell程序
 */
public class Shell {

    /**
     * 内核对象引用
     */
    private Kernel kernel;

    /**
     * 将shell绑定到kernel上
     */
    public Shell(Kernel kernel) {
        this.kernel = kernel;
    }

    /**
     * 打开shell
     */
    public void open() {
        loop(System.in);
    }

    /**
     * 将shell的输入重定向到文件
     */
    public void open(File file) {

        try {
            loop(new FileInputStream(file));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            exit(-1);
        }
    }

    /**
     * 将shell的输入和输出都重定向到文件
     */
    public void open(File inputFile, File outputFile) {
        try {
            loop(new FileInputStream(inputFile), new FileOutputStream(outputFile));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 将inputStream接到shell上<br/>
     * inputStream可以是System.in，也可以是FileInputStream
     */
    private void loop(InputStream inputStream) {
        Scanner scanner = new Scanner(inputStream);
        String inputText;
        System.out.print("shell>");
        //shell循环读入输入
        while (scanner.hasNext()) {
            inputText = scanner.nextLine();

            //跳过#开头的行（注释行）和空白行
            if (inputText.isEmpty())
                continue;
            else if (inputText.charAt(0) == '#')
                continue;

            //exit表示程序结束，否则继续读取下一行
            if (!inputText.equals("exit")) {
                System.out.println(fork(inputText));
                System.out.print("shell>");
            } else {
                System.out.println("exit.");
                kernel.setClock(false);
                break;
            }
        }
    }

    /**
     * 将shell的输入和输出接到inputStream和outputStream上
     */
    private void loop(InputStream inputStream, OutputStream outputStream) throws IOException {

        Scanner scanner = new Scanner(inputStream);
        String inputText;
        outputStream.write("shell>".getBytes());

        //shell循环读入输入
        while (scanner.hasNext()) {
            inputText = scanner.nextLine();

            //跳过#开头的行（注释行）和空白行
            if (inputText.isEmpty() || inputText.charAt(0) == '#') {
                continue;
            } else if (!inputText.equals("exit")) {
                //exit表示程序结束，否则继续读取下一行
                outputStream.write(fork(inputText).getBytes());
                outputStream.write('\n');
                outputStream.write("shell>".getBytes());
            } else {
                outputStream.write("exit.".getBytes());
                outputStream.write('\n');
                kernel.setClock(false);
                break;
            }
        }
    }

    /**
     * 将shell输入转换为内核API调用
     */
    private String fork(String inputText) {

        //由空白字符将命令断开
        String[] args = inputText.split("\\s+");

        switch (args[0]) {
            case "cr":
                return create(args);
            case "init":
                return init(args);
            case "de":
                return delete(args);
            case "req":
                return request(args);
            case "rel":
                return release(args);
            case "to":
                return timeOut(args);
            case "listp":
                return listProcesses(args);
            case "listr":
                return listResources(args);
            case "echo":
                return echo(args);
            default:
                return "bad command: " + args[0];
        }
    }

    /**
     * 初始化
     */
    private String init(String[] args) {

        if (args.length == 1) {

            //TODO 要建立一个init进程（虽然该进程啥也不做）

            return "Process init is running.";
        } else {
            return "init exception: no parameter required.";
        }
    }

    /**
     * 创建进程
     */
    private String create(String[] args) {

        if (args.length == 3) {

            //TODO 建立以args[1]为进程名、args[2]为进程优先级的进程

            return "Process " + args[1] + " is running.";
        } else {
            return "Process create failed: wrong parameter.";
        }
    }

    /**
     * 删除进程
     */
    private String delete(String[] args) {
        if (args.length == 2) {

            //TODO 删除进程

            return "delete pid " + args[1] + " success.";
        } else {
            return "delete failed: wrong parameter.";
        }
    }

    /**
     * 请求资源
     */
    private String request(String[] args) {
        if (args.length == 2) {

            //TODO 申请资源

            return "request resource " + args[1] + " success.";
        } else {
            return "request resource failed: wrong parameter.";
        }
    }

    /**
     * 释放资源
     */
    private String release(String[] args) {

        if (args.length == 2) {

            //TODO 释放资源

            return "release resource " + args[1] + " success.";
        } else {
            return "release resource failed: wrong parameter.";
        }
    }

    /**
     * 时间片用完
     */
    private String timeOut(String[] args) {

        if (args.length == 1) {

            //TODO 调用调度方法

            return "Time out.";
        } else {
            return "Time out exception: no parameter required.";
        }
    }

    private String listProcesses(String[] args) {

        //TODO 不要偷懒，把这个功能实现了啊
        return "list processes暂未完工，吴晓晗最懒惰了!";
    }

    private String listResources(String[] args) {

        //TODO 不要偷懒，把这个功能实现了啊
        return "list resources暂未完工，吴晓晗最懒惰了!";
    }

    /**
     * 回显
     */
    private String echo(String[] args) {

        StringBuilder stringBuilder = new StringBuilder();

        for (int i = 1; i < args.length; i++) {
            stringBuilder.append(args[i]);
            stringBuilder.append(' ');
        }

        return stringBuilder.toString();
    }
}
